package com.ruoyi.aitddx.service;

import cn.hutool.crypto.digest.DigestUtil;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ruoyi.aitcommon.anotation.ServiceLog;
import com.ruoyi.aitcommon.service.IAitEntityInfoService;
import com.ruoyi.aitcommon.utils.EntityCache;
import com.ruoyi.aitcommon.utils.ExceptionUtils;
import com.ruoyi.aitcommon.utils.JSONResult;
import com.ruoyi.aitcommon.utils.RestServiceUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Date;

@Service
public class DDXRestService {
    @Autowired
    IAitEntityInfoService infoService;
    @Autowired
    EntityCache entityCache;

    /**
     * 调用电电侠系统服务
     *
     * @param url   调用地址
     * @param param 接口参数(clientId,accessKey,loginUser)
     * @param data  数据
     * @return PRP返回json, 在外部解析
     */
    private JSONObject restInvoke(String url, Map<String, Object> param, Map<String, Object> data)
            throws Exception {
        ExceptionUtils.checkBlankOrUndefined(data,"没有data数据");

//      获取sign
        final Map<String, Object> head = this.getToken(param);
//        获取body
        final Map<String, Object> body = this.getBody(data);

//		远程调用
        JSONObject bodyjson = new JSONObject(body);
        final JSONObject retjson = RestServiceUtils.post(url, head, bodyjson);

//		处理服务返回
        if (!retjson.containsKey("statusCode"))
            throw new Exception("返回数据错误,无[statusCode]!");
        final Integer code = retjson.getInteger("statusCode");
        final String message = retjson.getString("message");
        if (code != 200) {
            String msg = String.format("返回报错,statusCode:[%s],message[%s]", code, message);
            throw new Exception(msg);
        }
        return retjson;
    }

    /**
     * 构造签名(Sign) head
     *
     * @param param 接口参数(接口参数(clientId,accessKey,loginUser))
     * @return http head
     */
    private Map<String, Object> getToken(Map<String, Object> param) throws Exception {
        final Object key = param.get("key");
        ExceptionUtils.checkBlankOrUndefined(key, "key不能为空");
        final int timestamp = (int) new Date().getTime();
//        构造sign
        final String plainText = String.valueOf(timestamp)
                +DigestUtil.md5Hex(key.toString()).toUpperCase();
        final String sign= DigestUtil.md5Hex(plainText).toUpperCase();
//        构造Head
        Map<String, Object> retmap = new LinkedHashMap<>();
        retmap.put("Sign", sign);
        retmap.put("Timestamp", timestamp);
        return retmap;
    }

    /**
     * 将数据按照Body格式进行封装
     *
     * @param data 数据Map
     * @return body json
     */
    private Map<String, Object> getBody(Map<String, Object> data) {
         return data;
    }

    /**
     * 保存接口封装
     *
     * @param datas      数据集合
     * @param param      接口参数
     * @param url        接口地址
     * @param entityInfo 实体信息
     */
    @ServiceLog("保存服务")
    public List<JSONObject> entitySave(List<Map<String, Object>> datas, Map<String, Object> param
            , String url, JSONObject entityInfo) throws Exception {
        List<JSONObject> retlist = new ArrayList<JSONObject>();

        ExceptionUtils.checkBlankOrUndefined(param, "param");
        ExceptionUtils.checkBlankOrUndefined(url, "url为空");
        ExceptionUtils.checkBlankOrUndefined(entityInfo, "entityInfo为空");

//		过滤缓存
        final List<Map<String, Object>> filterList = entityCache.filterEntityChange(entityInfo, datas);

        for (Map<String, Object> data : filterList) {
//			循环单条处理
            try {
//				调用接口
                JSONObject retjson = this.restInvoke(url, param, data);
//				处理实体日志和缓存
                infoService.insertAitEntityInfo(entityInfo, data, null);
//				处理返回
                retlist.add(retjson);
            } catch (Exception ex) {
//				处理实体日志和缓存-失败信息
                infoService.insertAitEntityInfo(entityInfo, data, ex);
//				处理返回
                retlist.add(JSONResult.error(ex.getMessage()));
            }
        }
        return retlist;
    }

}
